<script setup lang="ts">
import { ref, computed } from 'vue'
import { testProtocolParsing } from '@/service/api/deviceType'
import NovaIcon from '@/components/common/NovaIcon.vue'
import { NAlert, NButton, NInput, NModal, NSpace, NSpin, NSelect, NTag, NEmpty, NCard } from 'naive-ui'

defineOptions({ name: 'ProtocolTestModal' })

interface Props {
  visible: boolean
  driver: string
}

const props = withDefaults(defineProps<Props>(), {
  visible: false,
  driver: '',
})

interface Emits {
  (e: 'update:visible', visible: boolean): void
}

const emit = defineEmits<Emits>()

const localVisible = computed({
  get: () => props.visible,
  set: (val) => emit('update:visible', val),
})

const messageData = ref('')
const messageFormat = ref<'hex' | 'base64'>('hex')
const isTesting = ref(false)
const testResult = ref<any>(null)
const testError = ref('')

const formatOptions = [
  { label: '十六进制 (HEX)', value: 'hex' },
  { label: 'Base64', value: 'base64' },
]

async function handleTest() {
  if (!messageData.value.trim()) {
    window.$message.warning('请输入报文数据')
    return
  }

  if (!props.driver) {
    window.$message.warning('未选择协议')
    return
  }

  // 验证数据格式
  const trimmedData = messageData.value.trim()
  if (messageFormat.value === 'hex') {
    // 验证十六进制格式
    const cleanData = trimmedData.replace(/\s/g, '')
    if (!/^[0-9A-Fa-f]*$/.test(cleanData)) {
      window.$message.error('十六进制数据格式错误，只能包含 0-9 和 A-F')
      return
    }
    if (cleanData.length % 2 !== 0) {
      window.$message.error('十六进制数据长度必须是偶数')
      return
    }
  }

  isTesting.value = true
  testResult.value = null
  testError.value = ''

  try {
    const { isSuccess, data, message } = await testProtocolParsing(props.driver, {
      messageData: trimmedData,
      format: messageFormat.value,
    })

    if (isSuccess) {
      testResult.value = data
      window.$message.success('协议解析成功')
    } else {
      testError.value = message || '协议解析失败'
      window.$message.error(testError.value)
    }
  } catch (e: any) {
    testError.value = e.message || '测试失败'
    window.$message.error(testError.value)
  } finally {
    isTesting.value = false
  }
}

function clearResult() {
  testResult.value = null
  testError.value = ''
  messageData.value = ''
}

function showFormatHelp() {
  const helpText = `报文数据格式要求：

【十六进制格式 (HEX)】
- 只能包含数字 0-9 和字母 A-F (大小写都可以)
- 可以用空格分隔字节，例如：68 30 04 00 05 24
- 也可以不分隔，例如：683004000524
- 长度必须是偶数（每两个字符代表一个字节）

【Base64 格式】
- 标准 Base64 编码的字符串

【常见问题】
1. "十六进制数据格式错误" - 检查是否包含非 0-9, A-F 的字符
2. "十六进制数据长度必须是偶数" - 检查字符数是否是偶数
3. "0x68起始符未找到" - 报文格式可能不匹配该协议

【示例】
有效的十六进制报文：
FE FE FE 68 10 07 04 20 51 01 24 00 81 16 90 1F 00 00 00 00 00 2C 00 00 00 00 2C 00 00 00 00 00 00 00 00 FF B6 16`
  
  window.$dialog.info({
    title: '数据格式帮助',
    content: helpText,
    positiveText: '关闭',
    style: {
      width: '600px',
    },
    contentStyle: {
      whiteSpace: 'pre-wrap',
      fontFamily: 'monospace',
      fontSize: '12px',
    },
  })
}
</script>

<template>
  <NModal
    v-model:show="localVisible"
    :title="`协议测试：${driver}`"
    preset="card"
    class="w-90vw h-85vh"
  >
    <NSpin :show="isTesting">
      <div class="h-full flex flex-col gap-16px" style="height: calc(85vh - 150px);">
        <!-- 输入区域 -->
        <div class="flex flex-col gap-12px">
          <div class="flex items-center gap-12px">
            <span class="font-semibold">报文数据</span>
            <NSelect
              v-model:value="messageFormat"
              :options="formatOptions"
              style="width: 200px"
              size="small"
            />
          </div>

          <NInput
            v-model:value="messageData"
            type="textarea"
            placeholder="输入报文数据（十六进制或 Base64 格式）"
            :autosize="{ minRows: 6, maxRows: 10 }"
            :input-props="{
              style: 'font-family: Consolas, Monaco, Courier New, monospace; font-size: 13px;'
            }"
          />

          <div class="flex gap-8px">
            <NButton
              type="primary"
              :loading="isTesting"
              @click="handleTest"
            >
              <template #icon>
                <NovaIcon icon="icon-park-outline:play" />
              </template>
              测试解析
            </NButton>
            <NButton @click="clearResult">
              清空结果
            </NButton>
            <NButton secondary size="small" @click="showFormatHelp">
              数据格式帮助
            </NButton>
          </div>
        </div>

        <!-- 结果区域 -->
        <div v-if="testResult || testError" class="flex-1 min-h-0 flex flex-col gap-12px">
          <div class="font-semibold">解析结果</div>

          <div v-if="testError" class="flex-1 min-h-0 overflow-auto">
            <NAlert type="error" :bordered="false">
              <template #header>
                ❌ 解析失败
              </template>
              {{ testError }}
            </NAlert>
          </div>

          <div v-else-if="testResult" class="flex-1 min-h-0 overflow-auto">
            <NAlert type="success" :bordered="false" class="mb-12px">
              <template #header>
                ✅ 协议检测通过
              </template>
              报文数据已成功解析
            </NAlert>

            <div class="space-y-12px">
              <!-- 检测结果概览 -->
              <div class="grid grid-cols-3 gap-12px">
                <NCard size="small" :bordered="true">
                  <div class="text-center">
                    <div class="text-12px text-gray-500 mb-4px">协议检测</div>
                    <div class="text-18px font-bold">
                      <span v-if="testResult.DetectProtocol" class="text-green-600">✓ 通过</span>
                      <span v-else class="text-red-600">✗ 失败</span>
                    </div>
                  </div>
                </NCard>
                <NCard size="small" :bordered="true">
                  <div class="text-center">
                    <div class="text-12px text-gray-500 mb-4px">设备地址</div>
                    <div class="text-16px font-mono font-bold text-blue-600">
                      {{ testResult.ExtractDeviceAddress || '-' }}
                    </div>
                  </div>
                </NCard>
                <NCard size="small" :bordered="true">
                  <div class="text-center">
                    <div class="text-12px text-gray-500 mb-4px">数据解析</div>
                    <div class="text-18px font-bold">
                      <span v-if="testResult.AnalysisRx?.Status === '0'" class="text-green-600">✓ 成功</span>
                      <span v-else class="text-red-600">✗ 失败</span>
                    </div>
                  </div>
                </NCard>
              </div>

              <!-- 数据解析详情 -->
              <NCard v-if="testResult.AnalysisRx" size="small" :bordered="true">
                <template #header>
                  <div class="flex items-center gap-8px">
                    <span class="font-semibold">📊 数据解析详情</span>
                  </div>
                </template>
                
                <!-- 基础信息 -->
                <div class="mb-16px pb-16px border-b border-gray-200">
                  <div class="grid grid-cols-2 gap-12px">
                    <div class="flex justify-between">
                      <span class="text-gray-600">状态：</span>
                      <NTag :type="testResult.AnalysisRx.Status === '0' ? 'success' : 'error'">
                        {{ testResult.AnalysisRx.Status === '0' ? '成功' : '失败' }}
                      </NTag>
                    </div>
                    <div v-if="testResult.AnalysisRx.FrameType" class="flex justify-between">
                      <span class="text-gray-600">帧类型：</span>
                      <NTag type="info">{{ testResult.AnalysisRx.FrameType }}</NTag>
                    </div>
                    <div class="flex justify-between">
                      <span class="text-gray-600">需要响应：</span>
                      <NTag :type="testResult.AnalysisRx.NeedResponse ? 'warning' : 'success'">
                        {{ testResult.AnalysisRx.NeedResponse ? '是' : '否' }}
                      </NTag>
                    </div>
                    <div class="flex justify-between">
                      <span class="text-gray-600">变量数量：</span>
                      <span class="font-bold">{{ testResult.AnalysisRx.Variable?.length || 0 }}</span>
                    </div>
                  </div>
                </div>

                <!-- 解析的变量 -->
                <div v-if="testResult.AnalysisRx.Variable && testResult.AnalysisRx.Variable.length > 0">
                  <div class="font-semibold mb-8px">📋 解析的变量</div>
                  <div class="space-y-8px">
                    <div
                      v-for="(variable, idx) in testResult.AnalysisRx.Variable"
                      :key="idx"
                      class="p-10px bg-gradient-to-r from-blue-50 to-transparent rounded border-l-3 border-blue-400"
                    >
                      <div class="flex justify-between items-start mb-6px">
                        <div>
                          <div class="font-semibold text-blue-700">{{ variable.name }}</div>
                          <div v-if="variable.description" class="text-12px text-gray-500">{{ variable.description }}</div>
                        </div>
                        <NTag size="small" type="info">{{ variable.type }}</NTag>
                      </div>
                      <div class="text-14px font-mono font-bold text-gray-800 bg-white px-8px py-4px rounded">
                        {{ variable.value }}
                      </div>
                    </div>
                  </div>
                </div>
                <div v-else class="text-center text-gray-400 py-16px">
                  暂无解析的变量
                </div>
              </NCard>

              <!-- 响应数据 -->
              <NCard v-if="testResult.AnalysisRx?.Response && testResult.AnalysisRx.Response.length > 0" size="small" :bordered="true">
                <template #header>
                  <span class="font-semibold">📤 响应数据</span>
                </template>
                <div class="flex flex-wrap gap-4px">
                  <div
                    v-for="(byte, idx) in testResult.AnalysisRx.Response"
                    :key="idx"
                    class="px-8px py-4px bg-blue-100 text-blue-700 rounded font-mono text-12px font-bold"
                  >
                    {{ String(byte).padStart(2, '0').toUpperCase() }}
                  </div>
                </div>
              </NCard>

              <!-- 原始 JSON -->
              <NCard size="small" :bordered="true">
                <template #header>
                  <span class="font-semibold">📝 原始数据</span>
                </template>
                <div class="bg-gray-900 text-gray-100 p-12px rounded font-mono text-11px overflow-auto max-h-200px">
                  <pre>{{ JSON.stringify(testResult, null, 2) }}</pre>
                </div>
              </NCard>
            </div>
          </div>
        </div>

        <div v-else class="flex-1 min-h-0 flex items-center justify-center">
          <NEmpty description="输入报文数据并点击测试解析" />
        </div>
      </div>
    </NSpin>

    <template #footer>
      <NSpace justify="end">
        <NButton @click="() => emit('update:visible', false)">
          关闭
        </NButton>
      </NSpace>
    </template>
  </NModal>
</template>

<style scoped>
.space-y-8px > * + * {
  margin-top: 8px;
}

.space-y-12px > * + * {
  margin-top: 12px;
}

.space-y-2px > * + * {
  margin-top: 2px;
}
</style>
